package org.metasketch.editor.toolbox.advanced;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.metasketch.ham.model.HumanActivityParticipationRelationLink;
import org.metasketch.reflection.RefUtil;

public class DeleteRelatedManager {

	static RefUtil util = new RefUtil();

	static Map<Class, List<Class>> deleteRelatedClasses = new HashMap<Class, List<Class>>();

	static Map<Class, Map<Class, List<String>>> deleteRelatedFieldnameClasses = new HashMap<Class, Map<Class, List<String>>>();

	static Map<Class, List<String>> deleteRelatedFieldNames = new HashMap<Class, List<String>>();

	public static void register(Class node, Class related) {
		List<Class> list = deleteRelatedClasses.get(node);
		if (list == null) {
			list = new ArrayList<Class>();
			deleteRelatedClasses.put(node, list);
		}
		list.add(related);
	}

	public static boolean isHit(Class node, Class related, String fieldName) {

		List<Class> relatedClasses = getRelated(node);
		if (relatedClasses != null && relatedClasses.contains(related))
			return true;

		if (fieldName == null)
			return false;

		List<String> fieldNames = getRelatedFieldNames(related);
		if (fieldNames != null && fieldNames.contains(fieldName))
			return true;

		List<String> names = getRelatedFieldnameClasses(node, related);
		if (names != null && names.contains(fieldName))
			return true;

		return false;
	}

	public static List<Class> getRelated(Class node) {
		return deleteRelatedClasses.get(node);
	}

	public static void register(Class node, Class related, String fielName) {
		Map<Class, List<String>> map = deleteRelatedFieldnameClasses.get(node);
		if (map == null) {
			map = new HashMap<Class, List<String>>();
			deleteRelatedFieldnameClasses.put(node, map);
		}

		List<String> list = map.get(related);
		if (list == null) {
			list = new ArrayList<String>();
			map.put(node, list);
		}

		list.add(fielName);
	}

	public static Map<Class, List<String>> getRelatedFieldnameClasses(Class node) {
		return deleteRelatedFieldnameClasses.get(node);
	}

	public static List<String> getRelatedFieldnameClasses(Class node,
			Class related) {
		Map<Class, List<String>> map = deleteRelatedFieldnameClasses.get(node);
		if (map == null)
			return null;

		return map.get(related);

	}

	public static void registerDependency(Class type, String... fieldNames) {
		List<String> names = deleteRelatedFieldNames.get(type);
		if (names == null) {
			names = new ArrayList<String>();
			deleteRelatedFieldNames.put(type, names);
		}
		names.addAll(Arrays.asList(fieldNames));
	}

	public static void registerDefaultRelationDependency(Class type)
			throws Exception {
		if (util.getField(type, "source") != null
				&& util.getField(type, "target") != null)
			registerDependency(type, "source", "target");
		else
			throw new Exception("Couldnt find a source nor target fields in "
					+ type);

	}

	public static List<String> getRelatedFieldNames(Class type) {
		return deleteRelatedFieldNames.get(type);
	}

}
